Set 是一個位於 java.util
套件中的介面,繼承自 Collection 介面。最主要的特性就是不允許集合中出現兩個相同的元素。當你試圖插入一個已經存在於集合中的元素時,Set 不會引發錯誤,但它也不會將重複的元素新增至set裡,因此集合中保有唯一性。
常用的實作類別有:
HashSet 基於哈希表來儲存數據,因此插入、查詢和刪除操作的時間複雜度通常是 O(1)。HashSet 不保證元素的順序,也不允許包含重複的元素。當不在意元素順序時,使用 HashSet 是個不錯的選擇。它的高效性來源於哈希表的特性。
哈希表(Hash Table)是一種用來快速查找資料的資料結構。它的核心是通過一個哈希函數,將要存儲的資料(比如數字、字串等)轉換為一個特定的數值,這個數值稱為哈希值,然後根據這個哈希值將資料儲存在對應的位置上,這個位置稱為桶(bucket)。
範例:
利用HashSet紀錄唯一IP
Set<String> ipAddresses = new HashSet<>();
ipAddresses.add("192.168.0.1");
ipAddresses.add("192.168.0.2");
ipAddresses.add("192.168.0.1"); // 重複的IP不會被記錄
System.out.println(ipAddresses); // output:[192.168.0.1, 192.168.0.2]
TreeSet 是基於紅黑樹的實現類。與 HashSet 不同,TreeSet 會對插入的元素進行排序,因此遍歷 TreeSet 時,元素會按照自然順序(以數字來說就是從小到大)或使用者自定義的順序排列。由於需要維持元素的順序,TreeSet 的操作效率相較於 HashSet 要低一些,插入、查找和刪除的時間複雜度為 O(log n)。
範例:
樂透號碼開獎,從小到大排列
import java.util.TreeSet;
public class WinningNumbers {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(30);
numbers.add(27);
numbers.add(5);
numbers.add(31);
numbers.add(11);
// 直接列印,將按照自然順序顯示
System.out.println(numbers); // output: [5, 11, 27, 30, 31]
}
}
LinkedHashSet 使用哈希表和雙向鏈表實現,使 LinkedHashSet 能夠保證元素的插入順序。因此,插入、查詢和刪除操作的時間複雜度通常為 O(1),與 HashSet 相似。
範例:
import java.util.LinkedHashSet;
public class LinkedHashSetExample {
public static void main(String[] args) {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Orange");
linkedHashSet.add("Apple");
// 遍歷元素,保持插入順序
for (String fruit : linkedHashSet) {
System.out.println(fruit);
}
}
}
// output: Apple
// output: Banana
// output: Orange